package com.lin.http.file;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.stream.ChunkedWriteHandler;

public class HttpStaticFileServerInitializer extends ChannelInitializer<SocketChannel> {
	private final SslContext sslContext;

	public HttpStaticFileServerInitializer(SslContext sslContext) {
		this.sslContext = sslContext;
	}

	@Override
	protected void initChannel(SocketChannel ch) throws Exception {
		ChannelPipeline pipeline = ch.pipeline();
		if (sslContext != null) {
			pipeline.addLast(sslContext.newHandler(ch.alloc()));
		}
		// Http编解码器
		pipeline.addLast(new HttpServerCodec());
		// Http聚合器，将各个Http消息部分聚合一个完整的Http消息
		// 它将HttpMessage(HttpRequest,HttpResponse)及其下面的HttpContents集合成一个FullHttpRequest或FullHttpResponse（取决于它是否用于处理请求或响应）
		// Http请求和响应是由许多部分组成，我们需要这些不同的部分聚合成一个完整的Http消息。
		// Netty为我们提供了HttpObjectAggregator聚合器，
		// 将Http消息不同部分聚合成HttpFullRequest和HttpFullResponse。
		pipeline.addLast(new HttpObjectAggregator(65536));
		// 由于文件传输可能使用ChunkedInput，所以这里需要加入ChunkedWriteHandler
		// ChunkedWriteHandler支持异步写入大的数据流，而且不会耗费大量的内存和导致内存溢出。
		// 在pipeline加入ChunkedWriteHandler之后，我们就可以写入ChunkedInput。
		pipeline.addLast(new ChunkedWriteHandler());
		pipeline.addLast(new HttpStaticFileServerHandler());
	}
}
